import { ref, computed } from 'vue'

interface LazyLoadingOptions {
  pageSize?: number
  threshold?: number
  preloadPages?: number
}

interface LazyLoadingState<T> {
  items: T[]
  loading: boolean
  hasMore: boolean
  error: string | null
}

export function useLazyLoading<T>(
  loadFunction: (page: number, pageSize: number) => Promise<T[]>,
  options: LazyLoadingOptions = {}
) {
  const { pageSize = 50, preloadPages = 1 } = options
  
  const state = ref<LazyLoadingState<T>>({
    items: [],
    loading: false,
    hasMore: true,
    error: null
  })
  
  const currentPage = ref(0)
  const loadedPages = ref(new Set<number>())
  
  // 加载指定页面
  const loadPage = async (page: number): Promise<T[]> => {
    if (loadedPages.value.has(page) || state.value.loading) {
      return []
    }
    
    try {
      state.value.loading = true
      state.value.error = null
      
      const newItems = await loadFunction(page, pageSize)
      
      if (newItems.length === 0) {
        state.value.hasMore = false
        return []
      }
      
      // 将新项目插入到正确位置
      const startIndex = page * pageSize
      const updatedItems = [...state.value.items]
      
      for (let i = 0; i < newItems.length; i++) {
        updatedItems[startIndex + i] = newItems[i] as any
      }
      
      state.value.items = updatedItems
      loadedPages.value.add(page)
      
      if (newItems.length < pageSize) {
        state.value.hasMore = false
      }
      
      return newItems
    } catch (error) {
      state.value.error = error instanceof Error ? error.message : '加载失败'
      throw error
    } finally {
      state.value.loading = false
    }
  }
  
  // 加载下一页
  const loadNext = async (): Promise<T[]> => {
    if (!state.value.hasMore || state.value.loading) {
      return []
    }
    
    const nextPage = currentPage.value + 1
    const result = await loadPage(nextPage)
    currentPage.value = nextPage
    
    return result
  }
  
  // 预加载页面
  const preloadPage = async (page: number) => {
    if (loadedPages.value.has(page) || !state.value.hasMore) {
      return
    }
    
    try {
      await loadPage(page)
    } catch (error) {
      // 预加载失败不影响主流程
      console.warn(`预加载页面 ${page} 失败:`, error)
    }
  }
  
  // 根据滚动位置预加载
  const handleScroll = (scrollTop: number, _containerHeight: number, itemHeight: number) => {
    const currentIndex = Math.floor(scrollTop / itemHeight)
    const currentPageIndex = Math.floor(currentIndex / pageSize)
    
    // 预加载当前页面附近的页面
    for (let i = 0; i <= preloadPages; i++) {
      const targetPage = currentPageIndex + i
      if (targetPage > currentPage.value && state.value.hasMore) {
        preloadPage(targetPage)
      }
    }
  }
  
  // 重置状态
  const reset = () => {
    state.value = {
      items: [],
      loading: false,
      hasMore: true,
      error: null
    }
    currentPage.value = 0
    loadedPages.value.clear()
  }
  
  // 初始加载
  const initialize = async () => {
    reset()
    await loadNext()
  }
  
  return {
    state: computed(() => state.value),
    items: computed(() => state.value.items),
    loading: computed(() => state.value.loading),
    hasMore: computed(() => state.value.hasMore),
    error: computed(() => state.value.error),
    loadNext,
    loadPage,
    handleScroll,
    reset,
    initialize
  }
}